const mqtt = require('@/utils/mqtt/mqtt.min.js');
const {
	logs
} = require('@/utils/logs.js');

class mqttHandle {
	constructor() {
		this.client = null;
		this.processedUserGroups = new Set(); //处理家庭组消息去重
	}
	// 创建MQTT
	createConnect() {
		// #ifdef MP-WEIXIN
		let connectUrl = `wxs://jfmq-v2.xmcsrv.net:11883/mqtt`; //线上;
		// #endif
		// #ifdef H5
		let connectUrl = `wss://jfmq-v2.xmcsrv.net:11883/mqtt`; //线上;
		// #endif
		// let connectUrl = `wxs://jfmq-v2-pre.xmcsrv.net:11883/mqtt`;//测试;
		let connect = {
			clientId: `mini:${uni.getStorageSync('openId')}`,
			username: uni.getStorageSync('userInfo').userId,
			password: uni.getStorageSync('accessToken'),
			clean: false,
			keepalive: 10, //保活时间
			protocolVersion: 4, //协议版本
			reconnectPeriod: 1000, //1000毫秒，两次重新连接之间的间隔
			connectTimeout: 10000, //1000毫秒，两次重新连接之间的间隔
			resubscribe: true //如果连接断开并重新连接，则会再次自动订阅已订阅的主题（默认true）
		}
		if (this.client == null || this.client.connented == false) {
			try {
				this.client = mqtt.connect(connectUrl, connect);
				this.setupEventListeners();
			} catch (error) {
				console.log("MQTT 创建失败", error);
				logs({
					info: 'MQTT 创建失败'
				})
			}
		}
	}
	// 链接MQTT
	setupEventListeners() {
		this.client.on("connect", () => {
			console.log("MQTT 连接成功!");
			uni.$emit('mqttConnectSuccess')
			logs({
				info: 'MQTT 连接成功'
			})
		});

		this.client.on('message', (topic, message) => {
			this.handleMqttMessage(topic, message)
		})

		this.client.on('reconnect', (reconnect) => {
			console.log(reconnect,'MQTT 正在重连');
			logs({
				info: 'MQTT 正在重连'
			});
		})

		this.client.on("error", (error) => {
			console.log("MQTT 链接错误", error);
			logs({
				info: 'MQTT 链接错误',
				error: error
			})
		});
		
		this.client.on('disconnect', (packet) => {
			console.log(packet,'MQTT在收到 Broker 发送过来的断开连接的报文时触发disconnect');
			logs({
				info: 'MQTT在收到 Broker 发送过来的断开连接的报文时触发disconnect'
			});
		})
		
		this.client.on('offline', () => {
			console.log('MQTT当客户端下线时触发offline');
			logs({
				info: 'MQTT当客户端下线时触发offline'
			});
		})
		
		this.client.on('close', () => {
			console.log('MQTT在断开连接以后触发close');
			logs({
				info: 'MQTT在断开连接以后触发close'
			});
		})
	}
	// MQTT 消息处理
	handleMqttMessage(topic, message) {
		let info = JSON.parse(message);
		// console.log('收到 MQTT 消息:', topic,info);
		logs({
			info: '收到 MQTT 消息',
			topic: topic,
			message: message.toString()
		})
		if (topic.includes("/group/")) {
			this.groupMessage(message)
		} else {
			if(topic.endsWith('/alarmEvent')){
				uni.$emit('onAlarmEventMessage', message);
				this.messageAlarmEvent(message)
				return
			}
			uni.$emit('onWebsocketMessage', message);
			this.messageHandling(message)
		}
		if (info) {
			info.props.forEach((item) => {
				//门铃来电
				if (item.propCode == "doorLockCall") {
					console.log('门铃来电');
					uni.$emit('ondoorLockCallMessage', item);
				}
				if (item.propCode == "remoteUnlock") {
					console.log('开锁成功');
					uni.$emit('successUnlocking', item);
				}
			})
		}
	}
	// 家庭组消息去重
	groupMessage(message) {
		// console.log("家庭组数据:", JSON.parse(message));
		let data = JSON.parse(message)
		let userGroupId = data.props[0].propValue.userGroupId;
		let propCode = data.props[0].propCode;
		// 生成类型唯一key，结合 userGroupId 和 propCode
		let compositeKey = `${userGroupId}_${propCode}`;
		// 如果 compositeKey 在 2 秒内已经被处理过，则不再处理
		if (this.processedUserGroups.has(compositeKey)) return;
		// 标记 compositeKey 为已处理
		this.processedUserGroups.add(compositeKey);
		// 处理数据
		this.processData(message);
		// 在 2 秒后从 processedUserGroups 集合中移除 compositeKey
		setTimeout(() => this.processedUserGroups.delete(compositeKey), 2600);
	}
	// 去重处理后的数据
	processData(message) {
		console.log("处理后的家庭组数据:", JSON.parse(message));
		uni.$emit('onWebsocketMessage', message);
		this.messageHandling(message)
	}
	// 告警消息处理
	messageAlarmEvent(message) {
		let info = JSON.parse(message);
		let readStatus =  uni.getStorageSync('readStatus')
		readStatus.forEach(item => {
			if(item.deviceNo === info.SerialNumber) {
				item.readStatus = false
			}
		})
		uni.setStorageSync('readStatus', readStatus)
		// console.log(readStatus, '告警消息读取状态')
		// console.log(info,'告警消息设备信息')
		let allDeviceList = uni.getStorageSync('allDeviceList')
		const pages = getCurrentPages();
		let pagePath = pages[pages.length-1].route
		// var device = allDeviceList.find(el => el.deviceNo  ==  info.SerialNumber)
		if (info.AlarmEvent == 'DoorLockClose') {}
		if (info.AlarmEvent == "DoorLockOpen") {
			if(pagePath == 'jvss/pagesDevice/device/doorbellCall/doorbellCall'){
				setTimeout(() => {
					uni.navigateBack()
				}, 1000)
			}
		}
		if (info.AlarmEvent == "DoorLockCall") {
			console.log('来电消息')
			// this.getDoorLockCall(message,info,'DoorLockCall')
		}
		if (info.AlarmMsg.includes('FamilyCall')) {
			console.log('家人来电消息')
			// this.getDoorLockCall(message,info,'FamilyCall')
		}
	}
	// 处理门锁来电
	getDoorLockCall(message,info,type){
		let pageList = [
			'jvss/pages/device/home',
			'jvss/pages/scene/home',
			'jvss/pages/cloud/cloud',
			'jvss/pages/mine/home',
			'jvss/pagesDevice/device/device-live/door-lock/cloudMsg',
			'jvss/pagesDevice/device/doorbellCall/doorbellCall',
			'jvss/pagesDevice/device/device-live/door-lock/doorLockHome',
		]
		const pages = getCurrentPages();
		let pagePath = pages[pages.length-1].route
		const data = {
		    page: 1,
		    limit: 999,
			deviceNo: info.SerialNumber
		};
		let device;
		getApp().globalData.api.getUserDeviceListByPage(data, (result) => {
			if(result.data.length>0){
				device = result.data.find(el => el.deviceNo  ==  info.SerialNumber)
				if(device){
					if (pageList.includes(pagePath)) {
					  if(pagePath == 'jvss/pagesDevice/device/doorbellCall/doorbellCall'){
						  uni.navigateBack()
					  }
					  uni.navigateTo({
					  	url:`/jvss/pagesDevice/device/doorbellCall/doorbellCall?type=${type}&message=${message}&device=${encodeURIComponent(JSON.stringify(device))}`
					  })
					} 
				}else{
					this.getSharedDeviceList((sharedDeviceList)=>{
						device = sharedDeviceList.find(el => el.deviceNo  ==  info.SerialNumber)
						if (pageList.includes(pagePath)) {
						  if(pagePath == 'jvss/pagesDevice/device/doorbellCall/doorbellCall'){
							  uni.navigateBack()
						  }
						  uni.navigateTo({
						  	url:`/jvss/pagesDevice/device/doorbellCall/doorbellCall?type=${type}&message=${message}&device=${encodeURIComponent(JSON.stringify(device))}`
						  })
						}
					})
				}
				console.log(device,'门铃来电获取设备信息')
			}
		});
	}
	//共享设备列表
	getSharedDeviceList(callback){
		let data = {
			page:1,
			limit:999,
		}
		getApp().globalData.api.getSharedDeviceList(data, (result) => {
			callback(result.data)
		})
	}
	// 家庭组 & 公共消息处理
	messageHandling(message) {
		let info = JSON.parse(message);
		let userinfo = uni.getStorageSync('userInfo');
		if (info) {
			info.props.forEach((item) => {
				//设备删除
				if (item.propCode == "deviceDel" || item.propCode == "deviceReset") {
					let deleteInfo = item.propValue
					deleteInfo.sn = info.sn;
					this.handleDeviceDelete(deleteInfo,item.propCode);
				}
				//用户被移除家庭组
				if (item.propCode == "userDel") {
					this.handleUserDelete(item.propValue, userinfo);
				}
				//用户删除自己家庭组
				if (item.propCode == "userGroupDel") {
					this.handleuserGroupDel(item.propValue)
				}
			})
		}
	}
	// 删除设备
	handleDeviceDelete(deleteInfo,type) {
		const sn = deleteInfo.sn;
		const name = deleteInfo.nickName || '';
		let deleteContent = `家庭组${deleteInfo.userGroupName}中的${sn}已被${name}用户删除`;
		if(type == 'deviceReset'){
			deleteContent = `家庭组${deleteInfo.userGroupName}中的${sn}已被用户重置`
		}
		let topic = '/device/' + sn;
		if(uni.getStorageSync(sn)){
			uni.removeStorageSync(sn);
		}
		// this.unsubscribe(topic);//删除设备取消订阅
		this.getUnsubscribe(sn,'device')
		// uni.showModal({
		// 	title: '提示',
		// 	confirmText: '确认',
		// 	confirmColor: '#1AC0BA',
		// 	showCancel: false,
		// 	content: deleteContent,
		// 	success: (res) => {},
		// });
	}
	// 用户被移除
	handleUserDelete(userDelInfo, userinfo) {
		let userDelContent = `您已被${userDelInfo.delBy}用户从家庭组${userDelInfo.userGroupName}中移除`;
		if (userinfo.userId == userDelInfo.userId && !userDelInfo.selfDel) {
			uni.showModal({
				title: '提示',
				confirmText: '确认',
				confirmColor: '#1AC0BA',
				showCancel: false,
				content: userDelContent,
				success: (res) => {}
			})
		}else{
			this.handleuserGroupDel(userDelInfo)
		}
	}
	// 处理删除家庭组取消订阅 取消家庭组下面设备的订阅
	handleuserGroupDel(value){
		let deviceList = [];
		let allDeviceList = uni.getStorageSync('allDeviceList');
		if(allDeviceList.length>0){
			deviceList = allDeviceList.filter(el => el.userGroupId  ==  value.userGroupId)
		}	
		if(deviceList.length>0){
			deviceList.forEach((item,index)=>{
				this.getUnsubscribe(item.deviceNo,'device')
			})
		}
		this.getUnsubscribe(value.userGroupId,'group')
		uni.$emit('userGroupDel',value);
	}
	// 订阅消息
	subscribe(topic) {
		// console.log(this.client,'this.client')
		this.client.subscribe(topic, {
			qos: 1
		}, (error, res) => {
			if (error) {
				console.log("MQTT 订阅失败", error);
				logs({
					info: 'MQTT 订阅失败',
					error: error
				})
				return;
			} else {
				// console.log("MQTT 订阅成功", res, topic);
				logs({
					info: 'MQTT 订阅成功',
					res: res,
					topic: topic
				})
			}
		});
	}
	// 处理取消订阅
	getUnsubscribe(data, topicType) {
		let topic = []
		if (topicType == 'device') {
			topic[0] = '/device/' + data
			topic[1] = '/device/' + data+'/alarmEvent'
		} else if (topicType == 'group') {
			topic[0] = '/group/' + data
		} else if (topicType == 'user') {
			topic[0] = '/user/' + data
		}else if (topicType == 'alarmEvent') {
			topic[0] = '/device/' + data+'/alarmEvent'
		}
		this.unsubscribe(topic,topicType)
	}
	//取消订阅
	unsubscribe(subscribe,topicType) {
		// 取消订阅名为 subscribe 的 Topic
		this.client.unsubscribe(subscribe, function(error) {
			if (error) {
				console.log('取消订阅失败=====', error)
			} else {
				console.log('取消订阅成功=====', subscribe)
				if(topicType == 'device'){
					let sn = subscribe[0].slice(8)
					let readList = uni.getStorageSync('readStatus')
					let readStatus = readList.filter((item, index) => item.deviceNo!=sn)
					// 判断在新UI二级页面的情况下返回首页
					uni.$emit('cancelSubscribe', sn)
					uni.setStorageSync('readStatus', readStatus)
				}
			}
		})
	}
	//接收消息
	getMessage(callback) {
		this.client.on('message', (topic, message) => {
			let msg = JSON.parse(message.toString())
			return callback(message.toString())
		})
	}
	//关闭消息
	close() {
		this.client.end();
		this.client = null;
		console.log(this.client, '已断链 MQTT')
		logs({
			info: 'MQTT链接断开',
		})
	}
}

export default mqttHandle;
